package org.rayson.server.http;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.util.concurrent.ConcurrentLinkedQueue;

import org.rayson.server.transport.ServerConnection;
import org.rayson.share.transport.ByteArrayBuffer;

public class ServerResponseWriter implements AsyncResponseWriter {

	private final ServerConnection connection;
	private ByteBuffer currentResponse;
	private final ConcurrentLinkedQueue<byte[]> queue;
	private static final ByteBuffer DUMMY_RESPONSE = ByteBuffer.allocate(0);

	public ServerResponseWriter(final ServerConnection connection) {
		super();
		this.connection = connection;
		queue = new ConcurrentLinkedQueue<>();
		currentResponse = DUMMY_RESPONSE;
	}

	@Override
	public void add(final HttpServerResponse response) {
		final ByteArrayBuffer bab = new ByteArrayBuffer();
		response.writeTo(bab);
		queue.add(bab.toByteArray());
		if (currentResponse == DUMMY_RESPONSE) {
			currentResponse = ByteBuffer.wrap(queue.remove());
		}
		connection.getChannel().interestOps(
				connection.getChannel().getInterestOps()
						| SelectionKey.OP_WRITE);
		connection.getChannel().wakeupSelector();
	}

	@Override
	public void write() throws IOException {
		connection.getChannel().write(currentResponse);
		if (!currentResponse.hasRemaining()) {
			if (queue.isEmpty()) {
				currentResponse = DUMMY_RESPONSE;
				connection.getChannel().interestOps(
						connection.getChannel().getInterestOps()
								& ~SelectionKey.OP_WRITE);
			} else {
				currentResponse = ByteBuffer.wrap(queue.remove());
			}
		}
	}

}